<?php

namespace App\Http\Controllers\Reservation;

use App\Http\Controllers\ApiController;
use App\Http\Requests\DoctorStoreRequest;
use App\Http\Requests\DoctorUpdateRequest;
use App\Project\Traits\SearchAble;
use App\User;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
use Illuminate\Http\Request;
use App\Project\Reserve\Doctor;

class DoctorController extends ApiController
{
    use SearchAble;

    protected $doctorQueryMap = [
        'name' => ['field' => 'tn_user_base.name', 'operator' => 'like'],
        'phone' => ['field' => 'tn_user_base.phone', 'operator' => '='],
    ];

    /**
     * @param \Illuminate\Http\Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function index(Request $request)
    {
        //  ->whereIs('doctor', 'admin.doctor') 使用该条件可以按用户角色筛选
        $users = User::onlyDoctors()->simpleField()->with(
            [
                'detail' => function (HasOne $hasOne) {
                    $hasOne->select(['account', 'job']);
                },
                'roles' => function (MorphToMany $many) {
                    $many->select(['id', 'name', 'title']);
                }
            ]
        )->where(
            $this->hospitalSearchWithAuth($request->input())
        )->orderBy('created_at', 'desc')->paginate();
//        dd($users->pluck('detail', 'id'));
        return $this->paginate($users, $this->doctorTransformer());
    }

    /**
     * @param array $search
     * @return array
     */
    protected function hospitalSearchWithAuth(array $search)
    {
        $auth = \Auth::user()->isAn('admin');

        if ($auth) {
            $this->doctorQueryMap['hospital_id'] = ['field' => 'tn_user_base.hospital_id', 'operator' => '='];
        }

        $where = $this->parseSearchQueryToWhere($search, $this->doctorQueryMap);

        if (!$auth) {
            $where[] = ['tn_user_base.hospital_id', '=', \Auth::user()->hospital_id];
        }

        return $where;
    }

    /**
     * @param \App\Http\Requests\DoctorStoreRequest $request
     * @return array
     */
    public function store(DoctorStoreRequest $request)
    {
        try {

            return \DB::transaction(function () use ($request) {

                $input = $request->input();

                $creator = new Doctor();

                $creator->create(
                    $input['name'], $input['phone'], $input['password'], $input['hospital_id']
                );

                if ($user = $creator->getDoctor()) {

                    $creator->setDoctorRole($input['role']);
                    $creator->setDoctorJob($input['job']);
                    $user->save();
                    return $this->format(['id' => $user->id]);
                }
                return $this->format([], '添加失败。', 40004);
            });


        } catch (\PDOException $exception) {
            return $this->format([], '添加失败。', 40004);
        } catch (\Exception $exception) {
            return $this->format([], $exception->getMessage(), 40004);
        }
    }

    /**
     * @param $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function edit($id)
    {
        $user = User::onlyDoctors()->simplefield()->with(
            [
                'detail' => function (HasOne $hasOne) {
                    $hasOne->select(['account', 'job']);
                },
                'roles' => function (MorphToMany $many) {
                    $many->select(['id', 'name', 'title']);
                }
            ]
        )->findOrFail($id);

        return $this->item($user, $this->doctorTransformer());
    }

    /**
     * @param \App\Http\Requests\DoctorUpdateRequest $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function update(DoctorUpdateRequest $request)
    {
        $input = $request->input();

        $doctor = new Doctor();

        $result = $doctor->update($input);

        $user = $doctor->getDoctor();

        $roles = $user->roles->pluck('name')->toArray();

        if (!in_array($input['role'], $roles)) {

            if (in_array('doctor', $roles)) {
                $user->retract('doctor');
            } elseif (in_array('nurse', $roles)) {
                $user->retract('nurse');
            }

            $doctor->setDoctorRole($input['role']);
            $user->save();
        }

        return $this->responseForUpdate($result);
    }

    /**
     * @param \Illuminate\Http\Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function destroy(Request $request)
    {
        $id = $request->input('ids');

        $method = (count($id) > 1) ? 'whereIn' : 'where';

        $result = User::$method('id', $id)->delete();

        return $this->responseForDelete($result);
    }

    /**
     * @return \Closure
     */
    protected function doctorTransformer()
    {
        $title = config('custom.doctor.title');

        return function (User $user) use ($title) {
//
            $data = [
                "id" => $user->id,
                "account" => $user->account,
                "name" => $user->name,
                "sex" => $user->sex,
                "age" => $user->age,
                "phone" => $user->phone,
                "hospital_id" => $user->hospital_id,
                "created_at" => $user->created_at->toDateTimeString(),
                "updated_at" => $user->updated_at->toDateTimeString(),
                "job" => [
                    'key' => $user->detail&&in_array($user->detail->job, $title) ? array_flip($title)[$user->detail->job] : '',
                    'value' => $user->detail?$user->detail->job:'',
                ]
            ];

            if ($user->roles->count() > 0) {
                $data["role"] = [
                    'key' => $user->roles->first()->name,
                    'value' => $user->roles->first()->title,
                ];
            } else {
                $data["role"] = [
                    'key' => '',
                    'value' => '无',
                ];
            }

            return $data;
        };
}
}
